package net.lzzy.practicesapi1.repositories;

import net.lzzy.practicesapi1.entities.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.UUID;

public interface UserRepository extends JpaRepository<User, UUID> {
    /**
     * 登录市检查用户密码是否匹配
     * @param userName 要检查的用户名
     * @param password 要检查的密码
     * @return 用户对象，不存在则为null
     */
    User findUserByUserNameAndPassword(String userName, String password);

    /**
     * 检查数据库中是否存在该用户名
     * @param userName 要检查用户名
     * @return 存在的数量
     */
    Integer countByUserName(String userName);
    /**登陆时根据用户名查找其注册时保存的salt
    //@param userName 要检查用户名
    //返回用户的salt
     */
    UserProjection findUserByUserName(String userName);
    List<User> findAllByOrderByUpdateTimeDesc();

    /**
     * 分页获取用户数据
     * @param pageable 分页参数，包括页码和每页大小
     * @return 按分页大小返回User表记录
     */
    List<User> findAllByOrderByUpdateTimeDesc(Pageable pageable);

    /**
     * 返回User表所有数据记录数
     * @return 用户记录数
     */
    Integer countAllBy();

    /**
     * 获取申请教师资格的所有用户记录
     * @param apply 是否申请教师
     * @return 申请/未申请教师的用户记录
     */
    List<User> findUsersByApplyTeacherOrderByUpdateTimeDesc(boolean apply);

    /**
     * 1.使用Query注解可进行自定义查询，面不用局限于方法名约定
     * 2.使用方法：①添加注解②使用命名参数如：kw表示方法参数③使用类似sql的jpal规则，但是字段名而非列名
     * 3.参数绑定：kw是占位符，需要方法参数中使用@Param注解将方法参数与占位符绑定
     * @param keyword 爱查询的关键词
     * @return 模糊查询的结果集
     */

    @Query("select u from User u where u.userName like concat('%', :kw, '%') or " +
            "u.nickName like concat('%', :kw, '%' ) or u.email like concat('%', :kw, '%') or " +
            "u.phone like concat('%', :kw, '%') order by u.updateTime desc ")
    List<User> findByQuery(@Param("kw") String keyword);
}
